package com.tau.egonetwork.gui.core;

import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

import com.tau.egonetwork.common.Log;
import com.tau.egonetwork.profiles.Group;
import com.tau.egonetwork.profiles.MainProfile;

public class PrioritizeGroupsDialog<T extends Comparable<T>> extends BasicDialog {

	private static final String KEY_INDEX = "index";
	
	protected MainProfile<T> mainProfile;
	
	private boolean changesWereMade = false;

	private final int numOfPriorities = 4;
	private Combo[] combos = new Combo[numOfPriorities];
	private String[] originalPriorities = new String[numOfPriorities];
	private String[] priorities = new String[numOfPriorities];

	private ArrayList<String> groups = new ArrayList<String>();
	
	public PrioritizeGroupsDialog(Shell parent, MainProfile<T> profile) {
		super(parent);
		this.mainProfile = profile;
	}

	@Override
	protected void createWindowContents() {
		
		shell.setText("Prioritize Groups");
		
		Composite priorityComposite = new Composite(shell, SWT.NONE);
		priorityComposite.setLayout(new GridLayout(2, false));
		GridData priorityCompositeGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
		priorityCompositeGridData.widthHint = 400;
		priorityComposite.setLayoutData(priorityCompositeGridData);
		
		//build groups list:
		groups.add(""); //empty string to enable removal of selection and the opportunity not to select
		if (mainProfile.getGroupsList() != null) {
			for (Group<T> g : mainProfile.getGroupsList()) {
				groups.add(g.getGroupName());
			}
		}
		
		//build initial priorities list (to compare and check if changes were made at the end):
		for (int i = 0; i < numOfPriorities; i++) {
			Group<T> g = mainProfile.getGroupsList().getPriority(i+1);
			if (g == null)
				break;
			originalPriorities[i] = g.getGroupName();
		}
		
		String[] texts = { "1st", "2nd", "3rd", "4th" };
		for (int i = 0; i < numOfPriorities; i++) {
		
			Label textLabel = new Label(priorityComposite, SWT.NONE);
			textLabel.setText(texts[i] + " Priority: ");
			textLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
			
			combos[i] = new Combo(priorityComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
			combos[i].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			combos[i].setData(KEY_INDEX, i);
			for (String s : groups)
				combos[i].add(s);
						
			combos[i].addListener(SWT.Selection, new Listener() {
				
				@Override
				public void handleEvent(Event arg0) {
					
					int comboIndex = Integer.parseInt(arg0.widget.getData(KEY_INDEX) + "");
					String selectedGroup = combos[comboIndex].getText();
					
					if (!groups.contains(selectedGroup)) {
						Log.writeLineToLog("PrioritizeGroupsDialog::ComboListener - " + selectedGroup + " selected but not in combo");
						return;
					}
					
					//remove selection from all other combos:
					if (!selectedGroup.equals("")) {
						for (int i = 0; i < numOfPriorities; i++) {
							if (i != comboIndex)
								combos[i].remove(selectedGroup);
						}
					}
					
					if (priorities[comboIndex] != null && !selectedGroup.equals(priorities[comboIndex]) && !priorities[comboIndex].equals("")) {
						//priority has changed - update other combos:
						for (int i = 0; i < numOfPriorities; i++) {
							if (i != comboIndex) {
								combos[i].add(priorities[comboIndex]);
							}
						}
					}
					
					//set selection to be new priority:
					priorities[comboIndex] = selectedGroup;
					
				}
			});
			
		}
		
		//set original values if exists:
		for (int i = 0; i < numOfPriorities; i++) {
			if (originalPriorities[i] != null) {
				combos[i].setText(originalPriorities[i]);
				Event e = new Event();
				e.widget = combos[i];
				combos[i].notifyListeners(SWT.Selection, e);
			}
		}
		
	}

	@Override
	protected Object setReturnValue() {
		return changesWereMade;
	}

	@Override
	protected void onOKClicked() {

		//first check priorities are legal (if there's a selection for 4th, there must be for 3, 2 and 1):
		//go from end and find first index that's not null:
		int notNull = numOfPriorities;
		for (int i = numOfPriorities - 1; i >= 0; i--) {
			if (priorities[i] != null && !priorities[i].equals("")) {
				notNull = i;
				break;
			}
		}
		
		if (notNull == numOfPriorities) {
			//everything is null, delete all priorities and exit:
			for (int i = 1; i <= numOfPriorities; mainProfile.getGroupsList().setPriority(i++, null));
			shell.close();
			return;
		}
		
		//go over notNull till beginning and make sure everything is not null:
		for (int i = notNull - 1; i >= 0; i--) {
			if (priorities[i] == null || priorities[i].equals("")) {
				EgoNetworkMessageBox mbox = new EgoNetworkMessageBox(shell, SWT.ICON_ERROR, SWT.OK);
				mbox.setText("Error");
				mbox.setMessage("Priority #" + (i+1) + " cannot be empty when priority #" + (notNull + 1) + " is not empty!");
				mbox.open();
				return;
			}
		}
		
		//priorities are legal - save them:
		for (int i = 0; i < numOfPriorities; i++) {
			//if not empty, save this priority:
			if (priorities[i] != null && !priorities[i].equals("")) {
				
				mainProfile.getGroupsList().setPriority(
						i+1, mainProfile.getGroupsList().get(getIndexOfGroupName(priorities[i])));

				if (!priorities[i].equals(originalPriorities[i]))
					changesWereMade = true;
				
			} else {
				mainProfile.getGroupsList().setPriority(i+1, null);
				if ((originalPriorities[i] != null && !originalPriorities[i].equals("")) || originalPriorities[i] != null) {
					changesWereMade = true;
				}
			}
		}
		
		shell.close();
		
	}
	
	private int getIndexOfGroupName(String groupName) {
		
		for (int i = 1; i < groups.size(); i++) {
			if (groups.get(i).equals(groupName))
				return i-1;
		}
		
		return -1;
	}

}
